﻿function Uri() {

    var self = this;

    var protocol = '';
    var host = '';
    var pathWithoutQuery = '';

    var queries = {
    };

    function parse(uri) {
        var protocolIndex = uri.indexOf('://');
        if (protocolIndex >= 0) {
            protocol = uri.substr(0, protocolIndex + 3);
            uri = uri.substr(protocolIndex + 3);
        }
        var pathIndex = uri.indexOf('/');
        if (pathIndex >= 0) {
            host = uri.substr(0, pathIndex);
            uri = uri.substr(pathIndex);
        } else {
            host = uri;
            uri = '/';
        }

        setPath(uri);
        return self;
    }

    function setPath(p) {
        var index = p.indexOf('?');
        if (index >= 0) {
            pathWithoutQuery = p.substr(0, index);
            var rest = p.substr(index + 1);
            queries = deserializeQuery(rest);
        } else {
            pathWithoutQuery = p;
            queries = {};
        }
    }

    function addQuery(name, value) {
        queries[name] = [value];
    }

    function deserializeQuery(query) {
        var res = {};
        var args = query.split('&');
        for (var i = 0; i < args.length; i++) {
            var arg = args[i];
            var kv = arg.split('=');
            var name = kv[0];
            var value = kv.length > 1 ? kv[1] : '';

            var existing = res[name];
            if (!existing) {
                existing = [];
                res[name] = existing;
            }

            existing.push(value);
        }
        return res;
    }
    
    function serializeQuery() {
        var res = '';
        var first = true;
        for (var name in queries) {
            var val = queries[name];
            if (val) {
                for (var i = 0; i < val.length; i++) {
                    var arg = val[i];

                    if (first) {
                        res += '?';
                        first = false;
                    } else {
                        res += '&';
                    }

                    res += name;
                    res += '=';
                    res += arg;
                }
            }
        }
        return res;
    }

    function getPath() {
        var res = pathWithoutQuery;
        var queryString = serializeQuery();
        res += queryString;
        return res;
    }
    
    function getQueries() {
        var res = {};
        for (var name in queries) {
            var query = queries[name];
            if (query) {
                var values = [];
                for (var i = 0; i < query.length; i++) {
                    var arg = query[i];
                    values.push(arg);
                }
                res[name] = values;
            }
        }
        return res;
    }

    this.getProtocol = function () {
        return protocol;
    };

    this.getHost = function () {
        return host;
    };

    this.getPath = getPath;

    this.getUrl = function () {
        var res = protocol;
        res += host;
        res += getPath();
        return res;
    };

    this.getUrlWithoutQuery = function () {
        var res = protocol;
        res += host;
        res += getPathWithoutQuery();
        return res;
    };
    
    this.getPathWithoutQuery = function () {
        return pathWithoutQuery;
    };

    this.parse = parse;
    this.addQuery = addQuery;
    this.getQueries = getQueries;
}